package com.yugao.fintech.antelope.system.controller;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yugao.fintech.antelope.base.exception.enums.GlobalErrorEnum;
import com.yugao.fintech.antelope.base.log.LogTag;
import com.yugao.fintech.antelope.base.log.OperateLog;
import com.yugao.fintech.antelope.base.log.enums.BusinessType;
import com.yugao.fintech.antelope.base.ram.ActionType;
import com.yugao.fintech.antelope.base.ram.RamResource;
import com.yugao.fintech.antelope.system.model.entity.SysTenant;
import com.yugao.fintech.antelope.system.service.SysTenantService;
import com.yugao.fintech.framework.assistant.utils.StringUtils;
import com.yugao.fintech.framework.assistant.utils.exception.BizException;
import com.yugao.fintech.framework.core.response.Resp;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.yugao.fintech.antelope.system.constants.SysErrorEnum.TENANT_NOT_EXISTS;

/**
 * 租户配置信息
 */
@Tag(name = "租户管理")
@LogTag(name = "租户管理")
@Slf4j
@RestController
@RequestMapping("/tenant")
public class SysTenantController {

    @Autowired
    private SysTenantService tenantService;

    @Operation(summary = "获取租户配置")
    @GetMapping(value = "/getConfig")
    public Resp<TenantConfigResp> getConfig() {
        TenantConfigResp resp = tenantService.getConfig();
        return Resp.ok(resp);
    }

    @Operation(summary = "获取列表数据")
    @GetMapping(value = "/pageTenant")
    @RamResource(action = "sys:tenant:query", name = "查询租户", type = ActionType.READ)
    public Resp<IPage<TenantResp>> pageTenant(TenantPageReq query) {
        IPage<TenantResp> resp = tenantService.pageTenant(query);
        return Resp.ok(resp);
    }

    @Operation(summary = "查询全部租户")
    @GetMapping(value = "/listAll")
    public Resp<List<SysTenant>> listAll() {
        List<SysTenant> sysTenantList = tenantService.listAll();
        return Resp.ok(sysTenantList);
    }

    /**
     * @deprecated
     */
    @Operation(summary = "通过域名获取租户")
    @GetMapping(value = "/getTenantByDomain")
    public Resp<SysTenant> getTenantByDomain(@RequestParam("domain") String domain) {
        SysTenant resp = tenantService.getByDomain(domain);
        return Resp.ok(resp);
    }

    @PostMapping(value = "/save")
    @Operation(summary = "保存租户")
    @OperateLog(summary = "新增租户", businessType = BusinessType.INSERT)
    @RamResource(action = "sys:tenant:save", name = "保存租户", type = ActionType.WRITE)
    public Resp<?> save(@RequestBody @Validated TenantSaveReq req) {
        Long tenantId = tenantService.saveTenant(req);
        if (Objects.nonNull(tenantId)) {
            return Resp.fail(GlobalErrorEnum.OPERATION_FAIL_CREATE);
        }
        return Resp.ok(tenantId);
    }

    @Operation(summary = "编辑租户")
    @PostMapping(value = "/update")
    @OperateLog(summary = "租户管理", businessType = BusinessType.UPDATE)
    @RamResource(action = "sys:tenant:update", name = "更新租户", type = ActionType.WRITE)
    public Resp<Long> update(@RequestBody @Validated TenantUpdateReq req) {
        boolean ok = tenantService.updateTenant(req);
        if (!ok) {
            return Resp.fail(GlobalErrorEnum.OPERATION_FAIL_UPDATE);
        }
        return Resp.ok(req.getId());
    }


    @Operation(summary = "通过id删除")
    @OperateLog(summary = "租户管理", businessType = BusinessType.DELETE)
    @RamResource(action = "sys:tenant:delete", name = "删除租户", type = ActionType.WRITE)
    @RequestMapping(value = "/delete", method = {RequestMethod.DELETE, RequestMethod.POST})
    public Resp<?> deleteTenant(@RequestParam(name = "id") Long id) {
        tenantService.batchDeleteTenant(Collections.singletonList(id));
        return Resp.ok("删除成功");
    }

    @Operation(summary = "批量删除")
    @OperateLog(summary = "删除租户", businessType = BusinessType.DELETE)
    @RamResource(action = "sys:tenant:delete", name = "删除租户", type = ActionType.WRITE)
    @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
    public Resp<?> deleteBatch(@RequestParam(name = "ids") String ids) {
        if (StringUtils.isEmpty(ids)) {
            return Resp.fail("未选中租户！");
        } else {
            String[] ls = ids.split(",");
            // 过滤掉已被引用的租户
            List<Long> idList = Arrays.stream(ls).filter(id -> tenantService.countUserLinkTenant(Long.valueOf(id)) == 0)
                    .map(Long::parseLong).collect(Collectors.toList());
            if (idList.size() > 0) {
                tenantService.batchDeleteTenant(idList);
                if (ls.length == idList.size()) {
                    return Resp.ok("删除成功！");
                } else {
                    return Resp.ok("部分删除成功！（被引用的租户无法删除）");
                }
            } else {
                return Resp.fail("选择的租户都已被引用，无法删除！");
            }
        }
    }

    @Operation(summary = "通过id查询租户详情")
    @GetMapping(value = "/getTenant")
    public Resp<TenantResp> getTenant(@RequestParam("id") String id) {
        if (!NumberUtil.isNumber(id)) {
            throw new BizException(TENANT_NOT_EXISTS);
        }
        TenantResp resp = tenantService.getTenantById(Long.parseLong(id));
        return Resp.ok(resp);
    }
}